from django.contrib import admin
from django.http import HttpResponseRedirect
from django.urls import path
from django.utils.html import format_html
from django.contrib import messages
from django.db.models import Count, Avg, Max, Sum
from django.template.response import TemplateResponse
from django.shortcuts import render
from datetime import datetime, timedelta
from .models import Level, Question, QuestionOption, UserAnswer, UserScore
from django.contrib.auth.models import User


@admin.register(Level)
class LevelAdmin(admin.ModelAdmin):
    """关卡管理"""
    list_display = ['level_id', 'level_name', 'difficulty_factor', 'question_count']
    list_editable = ['difficulty_factor']
    search_fields = ['level_name']
    
    def question_count(self, obj):
        return obj.question_set.count()
    question_count.short_description = '题目数量'


@admin.register(Question)
class QuestionAdmin(admin.ModelAdmin):
    """题目管理"""
    list_display = ['question_id', 'level', 'difficulty_label', 'content_short', 'correct_option_index', 'option_count']
    list_filter = ['level', 'difficulty_label']
    search_fields = ['content', 'level__level_name']
    autocomplete_fields = ['level']

    class QuestionOptionInline(admin.TabularInline):
        model = QuestionOption
        extra = 0
        fields = ['content']
    inlines = [QuestionOptionInline]
    
    def content_short(self, obj):
        return obj.content[:50] + '...' if len(obj.content) > 50 else obj.content
    content_short.short_description = '题目内容'

    def option_count(self, obj):
        return obj.questionoption_set.count()
    option_count.short_description = '选项数量'


@admin.register(QuestionOption)
class QuestionOptionAdmin(admin.ModelAdmin):
    """题目选项管理"""
    list_display = ['option_id', 'question_short', 'option_index', 'content', 'is_correct_option']
    list_filter = ['question__level']
    search_fields = ['content', 'question__content']
    
    def question_short(self, obj):
        return f'题目{obj.question.question_id}'
    question_short.short_description = '所属题目'
    
    def option_index(self, obj):
        # 获取该选项在题目中的序号（从1开始）
        options = list(obj.question.questionoption_set.order_by('option_id').values_list('option_id', flat=True))
        try:
            return options.index(obj.option_id) + 1
        except ValueError:
            return 0
    option_index.short_description = '选项序号'
    
    def is_correct_option(self, obj):
        return obj.question.correct_option_index == self.option_index(obj)
    is_correct_option.short_description = '是否正确答案'
    is_correct_option.boolean = True


@admin.register(UserAnswer)
class UserAnswerAdmin(admin.ModelAdmin):
    """用户答题记录管理"""
    list_display = ['answer_log_id', 'user_info', 'question', 'selected_option', 'is_correct', 'score_earned', 'created_at']
    list_filter = ['is_correct', 'created_at']
    date_hierarchy = 'created_at'
    autocomplete_fields = ['user', 'question', 'selected_option']
    search_fields = ['user__username', 'user__id']
    readonly_fields = ['score_earned', 'created_at']
    
    def user_info(self, obj):
        return f'{obj.user.username} (ID: {obj.user.id})'
    user_info.short_description = '答题用户'


# 自定义过滤器
class ScoreRangeFilter(admin.SimpleListFilter):
    """按积分范围过滤"""
    title = '积分范围'
    parameter_name = 'score_range'
    
    def lookups(self, request, model_admin):
        return (
            ('0-100', '0-100分'),
            ('101-500', '101-500分'),
            ('501-1000', '501-1000分'),
            ('1001+', '1001分以上'),
        )
    
    def queryset(self, request, queryset):
        if self.value() == '0-100':
            return queryset.filter(total_score__range=(0, 100))
        elif self.value() == '101-500':
            return queryset.filter(total_score__range=(101, 500))
        elif self.value() == '501-1000':
            return queryset.filter(total_score__range=(501, 1000))
        elif self.value() == '1001+':
            return queryset.filter(total_score__gte=1001)


class ActivityFilter(admin.SimpleListFilter):
    """按活跃度过滤"""
    title = '活跃度'
    parameter_name = 'activity'
    
    def lookups(self, request, model_admin):
        return (
            ('active', '活跃用户 (最近7天有答题)'),
            ('inactive', '不活跃用户 (最近7天无答题)'),
            ('new', '新用户 (30天内加入)'),
        )
    
    def queryset(self, request, queryset):
        if self.value() == 'active':
            seven_days_ago = datetime.now() - timedelta(days=7)
            active_user_ids = UserAnswer.objects.filter(
                created_at__gte=seven_days_ago
            ).values_list('user_id', flat=True).distinct()
            return queryset.filter(user_id__in=active_user_ids)
        elif self.value() == 'inactive':
            seven_days_ago = datetime.now() - timedelta(days=7)
            active_user_ids = UserAnswer.objects.filter(
                created_at__gte=seven_days_ago
            ).values_list('user_id', flat=True)
            return queryset.exclude(user_id__in=active_user_ids)
        elif self.value() == 'new':
            thirty_days_ago = datetime.now() - timedelta(days=30)
            # 注意：需要用户模型有创建时间字段，这里用last_updated作为示例
            return queryset.filter(last_updated__gte=thirty_days_ago)


class RankFilter(admin.SimpleListFilter):
    """按排名范围过滤"""
    title = '排名范围'
    parameter_name = 'rank_range'
    
    def lookups(self, request, model_admin):
        return (
            ('top10', '前10名'),
            ('top50', '前50名'),
            ('top100', '前100名'),
            ('top500', '前500名'),
        )
    
    def queryset(self, request, queryset):
        if self.value() == 'top10':
            return queryset.filter(rank__lte=10)
        elif self.value() == 'top50':
            return queryset.filter(rank__lte=50)
        elif self.value() == 'top100':
            return queryset.filter(rank__lte=100)
        elif self.value() == 'top500':
            return queryset.filter(rank__lte=500)


class UserScoreAdmin(admin.ModelAdmin):
    """用户积分管理"""
    list_display = ['user_info', 'total_score', 'rank', 'last_updated', 'answer_count', 'accuracy_rate', 'action_buttons']
    list_filter = ['rank', 'last_updated', ScoreRangeFilter, ActivityFilter, RankFilter]
    search_fields = ['user__username', 'user__id']
    readonly_fields = ['total_score', 'rank', 'last_updated', 'answer_count', 'accuracy_rate']
    ordering = ['rank']
    list_per_page = 25
    
    def user_info(self, obj):
        return f'{obj.user.username} (ID: {obj.user.id})'
    user_info.short_description = '用户'
    
    def answer_count(self, obj):
        return UserAnswer.objects.filter(user=obj.user).count()
    answer_count.short_description = '答题数量'
    
    def accuracy_rate(self, obj):
        correct_count = UserAnswer.objects.filter(user=obj.user, is_correct=True).count()
        total_count = UserAnswer.objects.filter(user=obj.user).count()
        if total_count > 0:
            return f"{round(correct_count/total_count*100, 1)}%"
        return "0%"
    accuracy_rate.short_description = '正确率'
    
    def action_buttons(self, obj):
        return format_html(
            '<a href="/admin/challenge/userscore/{}/change/" class="button">详情</a>',
            obj.user_id
        )
    action_buttons.short_description = '操作'
    action_buttons.allow_tags = True
    
    def get_queryset(self, request):
        """优化查询性能，预加载相关数据"""
        qs = super().get_queryset(request)
        return qs.select_related('user')
    
    def changelist_view(self, request, extra_context=None):
        """添加自定义的统计数据到变更列表页面"""
        response = super().changelist_view(request, extra_context=extra_context)
        
        if hasattr(response, 'context_data'):
            # 获取查询参数
            q = request.GET.get('q', '')
            rank_filter = request.GET.get('rank', '')
            
            # 基础查询
            queryset = UserScore.objects.all()
            
            # 应用搜索过滤
            if q:
                queryset = queryset.filter(user__username__icontains=q)
            
            # 应用排名过滤
            if rank_filter:
                if rank_filter == 'top10':
                    queryset = queryset.filter(rank__lte=10)
                elif rank_filter == 'top50':
                    queryset = queryset.filter(rank__lte=50)
                elif rank_filter == 'top100':
                    queryset = queryset.filter(rank__lte=100)
            
            # 计算统计信息
            total_users = queryset.count()
            avg_score = queryset.aggregate(avg=Avg('total_score'))['avg'] or 0
            max_score = queryset.aggregate(max=Max('total_score'))['max'] or 0
            
            response.context_data['total_users'] = total_users
            response.context_data['avg_score'] = round(avg_score, 2)
            response.context_data['max_score'] = max_score
        
        return response


# 自定义过滤器
class ScoreRangeFilter(admin.SimpleListFilter):
    """按积分范围过滤"""
    title = '积分范围'
    parameter_name = 'score_range'
    
    def lookups(self, request, model_admin):
        return (
            ('0-100', '0-100分'),
            ('101-500', '101-500分'),
            ('501-1000', '501-1000分'),
            ('1001+', '1001分以上'),
        )
    
    def queryset(self, request, queryset):
        if self.value() == '0-100':
            return queryset.filter(total_score__range=(0, 100))
        elif self.value() == '101-500':
            return queryset.filter(total_score__range=(101, 500))
        elif self.value() == '501-1000':
            return queryset.filter(total_score__range=(501, 1000))
        elif self.value() == '1001+':
            return queryset.filter(total_score__gte=1001)


class ActivityFilter(admin.SimpleListFilter):
    """按活跃度过滤"""
    title = '活跃度'
    parameter_name = 'activity'
    
    def lookups(self, request, model_admin):
        return (
            ('active', '活跃用户 (最近7天有答题)'),
            ('inactive', '不活跃用户 (最近7天无答题)'),
            ('new', '新用户 (30天内加入)'),
        )
    
    def queryset(self, request, queryset):
        if self.value() == 'active':
            seven_days_ago = datetime.now() - timedelta(days=7)
            active_user_ids = UserAnswer.objects.filter(
                created_at__gte=seven_days_ago
            ).values_list('user_id', flat=True).distinct()
            return queryset.filter(user_id__in=active_user_ids)
        elif self.value() == 'inactive':
            seven_days_ago = datetime.now() - timedelta(days=7)
            active_user_ids = UserAnswer.objects.filter(
                created_at__gte=seven_days_ago
            ).values_list('user_id', flat=True)
            return queryset.exclude(user_id__in=active_user_ids)
        elif self.value() == 'new':
            thirty_days_ago = datetime.now() - timedelta(days=30)
            # 注意：需要用户模型有创建时间字段，这里用last_updated作为示例
            return queryset.filter(last_updated__gte=thirty_days_ago)


class RankFilter(admin.SimpleListFilter):
    """按排名范围过滤"""
    title = '排名范围'
    parameter_name = 'rank_range'
    
    def lookups(self, request, model_admin):
        return (
            ('top10', '前10名'),
            ('top50', '前50名'),
            ('top100', '前100名'),
            ('top500', '前500名'),
        )
    
    def queryset(self, request, queryset):
        if self.value() == 'top10':
            return queryset.filter(rank__lte=10)
        elif self.value() == 'top50':
            return queryset.filter(rank__lte=50)
        elif self.value() == 'top100':
            return queryset.filter(rank__lte=100)
        elif self.value() == 'top500':
            return queryset.filter(rank__lte=500)


class ChallengeAdminSite(admin.AdminSite):
    """挑战系统管理站点"""
    
    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('leaderboard/', self.admin_view(self.leaderboard_view), name='challenge_leaderboard'),
            path('update_ranks/', self.admin_view(self.update_ranks_view), name='challenge_update_ranks'),
            path('stats/', self.admin_view(self.stats_view), name='challenge_stats'),
        ]
        return custom_urls + urls
    
    def leaderboard_view(self, request):
        """排行榜页面"""
        # 获取排行榜数据
        top_users = UserScore.objects.order_by('-total_score')[:50]
        
        # 计算统计信息
        total_users = UserScore.objects.count()
        avg_score = UserScore.objects.aggregate(avg=Avg('total_score'))['avg'] or 0
        max_score = UserScore.objects.aggregate(max=Max('total_score'))['max'] or 0
        
        # 计算答题统计
        total_answers = UserAnswer.objects.count()
        correct_answers = UserAnswer.objects.filter(is_correct=True).count()
        overall_accuracy = round(correct_answers / total_answers * 100, 2) if total_answers > 0 else 0
        
        context = {
            'title': '排行榜管理',
            'top_users': top_users,
            'total_users': total_users,
            'avg_score': round(avg_score, 2),
            'max_score': max_score,
            'total_answers': total_answers,
            'correct_answers': correct_answers,
            'overall_accuracy': overall_accuracy,
            'opts': self.model._meta,
        }
        
        return TemplateResponse(request, 'admin/challenge/leaderboard.html', context)
    
    def update_ranks_view(self, request):
        """手动更新排名"""
        try:
            # 实现更新排名逻辑
            user_scores = UserScore.objects.order_by('-total_score')
            rank = 1
            for user_score in user_scores:
                user_score.rank = rank
                user_score.save()
                rank += 1
            
            messages.success(request, f'成功更新了 {user_scores.count()} 名用户的排名！')
        except Exception as e:
            messages.error(request, f'更新排名失败: {str(e)}')
        
        return HttpResponseRedirect('/admin/challenge/leaderboard/')
    
    def stats_view(self, request):
        """统计信息页面"""
        # 总体统计
        total_levels = Level.objects.count()
        total_questions = Question.objects.count()
        total_users_with_scores = UserScore.objects.count()
        total_answers = UserAnswer.objects.count()
        
        # 关卡统计
        level_stats = []
        for level in Level.objects.all():
            level_questions = level.question_set.count()
            level_answers = UserAnswer.objects.filter(question__level=level).count()
            level_correct = UserAnswer.objects.filter(question__level=level, is_correct=True).count()
            
            level_stats.append({
                'level': level,
                'question_count': level_questions,
                'answer_count': level_answers,
                'correct_count': level_correct,
                'accuracy': round(level_correct / level_answers * 100, 2) if level_answers > 0 else 0
            })
        
        # 用户统计
        active_users = UserScore.objects.filter(total_score__gt=0).count()
        
        # 最近7天数据
        seven_days_ago = datetime.now() - timedelta(days=7)
        recent_answers = UserAnswer.objects.filter(created_at__gte=seven_days_ago).count()
        
        context = {
            'title': '挑战系统统计',
            'total_levels': total_levels,
            'total_questions': total_questions,
            'total_users_with_scores': total_users_with_scores,
            'active_users': active_users,
            'total_answers': total_answers,
            'recent_answers': recent_answers,
            'level_stats': level_stats,
            'opts': self.model._meta,
        }
        
        return TemplateResponse(request, 'admin/challenge/stats.html', context)


# 创建挑战系统管理站点
challenge_admin_site = ChallengeAdminSite(name='challenge_admin')

# 注册模型到挑战系统管理站点
challenge_admin_site.register(Level, LevelAdmin)
challenge_admin_site.register(Question, QuestionAdmin)
challenge_admin_site.register(QuestionOption, QuestionOptionAdmin)
challenge_admin_site.register(UserAnswer, UserAnswerAdmin)
challenge_admin_site.register(UserScore, UserScoreAdmin)

# 为自定义站点注册User以支持autocomplete_fields
class UserAutocompleteAdmin(admin.ModelAdmin):
    search_fields = ['username', 'email']

challenge_admin_site.register(User, UserAutocompleteAdmin)

# 也注册到默认管理站点（用于传统管理界面）
admin.site.register(UserScore, UserScoreAdmin)